﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SuperFox.SuperServiceReference;
using System.Collections.ObjectModel;

namespace SuperFox
{
    public partial class OrdersReview : UserControl
    {
        public OrdersReview()
        {
            InitializeComponent();
        }

        private SuperServiceClient client { get; set; }

        private ObservableCollection<int> OrderIds { get; set; }

        private int OrderListPos { get; set; }

        private ObservableCollection<DBOrders> Orders { get; set; }

        private ObservableCollection<DateTime> Months { get; set; }

        private List<OrderReviewProductObject> Products { get; set; }

        private List<SortMemeber> SortMembers { get; set; }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            client = null;
            client = ServiceConfig.Connect();

            client.GetOrderByIdCompleted += new EventHandler<GetOrderByIdCompletedEventArgs>(client_GetOrderByIdCompleted);
            client.GetAllOrderIDsCompleted += new EventHandler<GetAllOrderIDsCompletedEventArgs>(client_GetAllOrderIDsCompleted);

            client.GetAllOrderIDsAsync((App.Current.RootVisual as MainPage).CurrentUser.Programs.merc_id);
        
        }

        void client_GetAllOrderIDsCompleted(object sender, GetAllOrderIDsCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show("There was an error getting order data. Please try again later");
                return;
            }

            this.OrderIds = e.Result;

            this.Orders = new ObservableCollection<DBOrders>();

            this.OrderListPos = 0;

            this.LoadingProgress.Minimum = 0;
            this.LoadingProgress.Maximum = this.OrderIds.Count;


            client.GetOrderByIdAsync(this.OrderIds[OrderListPos]);
        }

        void client_GetOrderByIdCompleted(object sender, GetOrderByIdCompletedEventArgs e)
        {
            this.LoadingProgress.Value = this.OrderListPos + 1;

            this.Orders.Add(e.Result);

            this.OrderListPos++;

            if (OrderListPos >= this.OrderIds.Count)
            {

                // build the columns

                BuildColumns();

                this.MainGrid.Visibility = System.Windows.Visibility.Visible;
                this.PanelHolder.Visibility = System.Windows.Visibility.Visible;
                this.LoadingProgress.Visibility = System.Windows.Visibility.Collapsed;
                this.LoadingCaption.Visibility = System.Windows.Visibility.Collapsed;

                this.MainGrid.ItemsSource = this.Products;

                this.SortMembers = this.SortMembers.OrderBy(p => p.Date).ToList<SortMemeber>();


                this.SortCb.ItemsSource = this.SortMembers;
                this.SortCb.SelectedIndex = 0;

                return;
            }
            else
            {



                client.GetOrderByIdAsync(this.OrderIds[OrderListPos]);
            }
        }


        private bool ContainsMonths(DateTime d)
        {
            foreach (DateTime dt in this.Months)
            {
                if (dt.Year.Equals(d.Year) && dt.Month.Equals(d.Month))
                {
                    return true;
                }
            }

            return false;
        }

        private bool ContainsProduct(DbOrderProduct pr)
        {
            foreach(OrderReviewProductObject p in this.Products)
            {
                if (p.ID == pr.prod_id)
                {
                    return true;
                }
            }

            return false;
        }

        private void ProcessProducts(ObservableCollection<DbOrderProduct> prods, DateTime dt)
        {
            foreach (DbOrderProduct pr in prods)
            {
                if (!ContainsProduct(pr))
                {

                    OrderReviewProductObject p = new OrderReviewProductObject();

                    p.ID = pr.prod_id;
                    p.Name = pr.ordprod_productname;
                    p[dt.ToString("MMMMyyyy")] = pr.ordprod_quantity;

                    this.Products.Add(p);
                }
                else
                {
                    // add to the amount
                    foreach (OrderReviewProductObject orpo in this.Products)
                    {
                        if (orpo.ID == pr.prod_id)
                        {
                            int amount = (int)orpo[dt.ToString("MMMMyyyy")];

                            amount += pr.ordprod_quantity;

                            orpo[dt.ToString("MMMMyyyy")] = amount;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }

            
        }

        private void BuildColumns()
        {

            List<TextColumnExtension> columns = new List<TextColumnExtension>();

            this.SortMembers = new List<SortMemeber>();
            this.SortMembers.Add(new SortMemeber() { Date = new DateTime(), Item = "Name" });

            this.Products = new List<OrderReviewProductObject>();
            this.Months = new ObservableCollection<DateTime>();

            foreach (DBOrders ord in this.Orders)
            {
                if (!ContainsMonths(ord.ord_date))
                {
                    this.Months.Add(ord.ord_date);
                    this.SortMembers.Add(new SortMemeber() { Item = ord.ord_date.ToString("MMMM yyyy"), Date = ord.ord_date });
                }

                ProcessProducts(ord.Products, ord.ord_date);
            }



            columns.Add(new TextColumnExtension()
            {
                Header = "Product",
                CanUserSort = false,
                Date = new DateTime(),
                Binding = new System.Windows.Data.Binding()
                {
                    Mode = System.Windows.Data.BindingMode.OneWay,
                    Path = new PropertyPath("Name")
                }
            });

            foreach (DateTime dt in this.Months)
            {
                columns.Add(new TextColumnExtension()
                {
                    Header = dt.ToString("MMMM / yyyy"),
                    Date = dt,
                    Binding = new System.Windows.Data.Binding()
                    {
                        Mode = System.Windows.Data.BindingMode.OneWay,
                        Path = new PropertyPath("[" + dt.ToString("MMMMyyyy") + "]")
                    }
                });
            }

            columns = columns.OrderBy(p => (p as TextColumnExtension).Date).ToList<TextColumnExtension>();

            foreach (TextColumnExtension col in columns)
            {
                MainGrid.Columns.Add(col);
            }
        }


        private void SortCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SortGrid();
        }

        private void SortGrid()
        {
            string path = (SortCb.SelectedItem as SortMemeber).Date.ToString("MMMMyyyy");

            if (path == "Name")
            {
                this.MainGrid.ItemsSource = null;
                if ((bool)this.DecendingCb.IsChecked)
                {
                    this.Products = this.Products.OrderByDescending(p => p.Name).ToList<OrderReviewProductObject>();
                }
                else
                {
                    this.Products = this.Products.OrderBy(p => p.Name).ToList<OrderReviewProductObject>();
                }
                this.MainGrid.ItemsSource = this.Products;
            }
            else
            {

                this.MainGrid.ItemsSource = null;
                if ((bool)this.DecendingCb.IsChecked)
                {
                    this.Products = this.Products.OrderByDescending(p => p[path]).ToList<OrderReviewProductObject>();
                }
                else
                {
                    this.Products = this.Products.OrderBy(p => p[path]).ToList<OrderReviewProductObject>();
                }
                this.MainGrid.ItemsSource = this.Products;
            }

        }

        private void DecendingCb_Unchecked(object sender, RoutedEventArgs e)
        {
            if(SortCb.SelectedIndex != -1)
                SortGrid();
        }

        private void DecendingCb_Checked(object sender, RoutedEventArgs e)
        {
            if(SortCb.SelectedIndex != -1)
                SortGrid();
        }

        private void SortCb_Loaded(object sender, RoutedEventArgs e)
        {
            (sender as ComboBox).SelectedIndex = 0;
        }
    }
}
